<?php

namespace App\Services\ApplyGoldProductOrder;

use Closure;
use App\Models\User;
use App\Models\Order;
use App\Models\Address;
use Illuminate\Support\Facades\Redis;
use App\Http\Controllers\Api\V1\Requests\FormRequest;

class ApplyGoldProductOrderRequest extends FormRequest
{
    protected ?Address $address = null;

	public function rules(): array
	{
        $addressId =  (int)request('address');
        if ($addressId) {
            $this->address = Address::find($addressId);
        }

		return [
			'record' => [
				'string', $this->record(),
			],
			'address' => [
                'required',
				'integer',
                'min:1',
                $this->address(),
			]
		];
	}

	public function record(): Closure
	{
		return function ($key, $value, $fail) {

			$cid = $value;

			/**
			 * @var User $user
			 */
			$user = $this->user();

			if (!Redis::exists($cid)) {
				return $fail('目标记录不存在');
			} elseif (! $this->user()->isValidVip()) {
				return $fail('仅有效VIP会员可申请');
			} elseif (Redis::hGet($cid, 'user_id') != $user->id) {
				return $fail("目标记录无权操作");
			} elseif (Redis::hGet($cid, 'is_paying')) {
				return $fail('目标记录正在支付中');
			} elseif (! Redis::hGet($cid, 'is_paid')) {
				return $fail('目标记录未支付');
			} elseif (Redis::hGet($cid, 'is_resell_applying')) {
				return $fail('目标记录正在申请寄售');
			} elseif (Redis::hGet($cid, 'has_applied_to_resell')) {
				return $fail('目标记录已申请寄售');
			} elseif (Redis::hGet($cid, 'is_split_applying')) {
                return $fail("目标记录正在申请超额返");
            } elseif (Redis::hGet($cid, 'has_applied_to_split')) {
                return $fail("目标记录已申请超额返");
            } elseif (Redis::hGet($cid, 'is_take_applying')) {
				return $fail('目标记录正在申请发货');
			} elseif (Redis::hGet($cid, 'has_applied_to_take')) {
				return $fail('目标记录已申请发货');
			} elseif (! $this->isGoldCoinsEnough($cid)) {
                return $fail('账户余额不足');
            }

			return true;
		};
	}

    public function address(): Closure
    {
        return function ($attribute, $value, $fail) {
            if (!$this->address) {
                return $fail('地址不存在');
            } elseif (!Order::isAddressSupported($this->address)) {
                return $fail('地址不在配送范围');
            }
            return true;
        };
    }

    public function isGoldCoinsEnough($cid): bool
    {
        /**
         * @var User $user
         */
        $user = $this->user();
        $cashPrice = Redis::hGet($cid, 'pay_cash_price');
        return $user->isGoldCoinsEnough($cashPrice);
    }

    public function getAddress(): Address
    {
        return $this->address;
    }
}
